#include <stdio.h>


//#include "Python.h"

#ifdef _DEBUG
    #define _LAST_IS_DEGBUG
    #undef _DEBUG
    #include "Python.h"
    #include "numpy/arrayobject.h"
    #pragma comment(lib,"python27.lib")
#else
    #include "Python.h"
    #include "numpy/arrayobject.h"
#endif

#ifdef _LAST_IS_DEGBUG
    #define _DEBUG
    #undef _LAST_IS_DEGBUG
#endif

int main()
{
    Py_Initialize();

//    import_array(); //load numpy api
    if(_import_array() < 0){
        printf("NumPy lib load failed!");
    }

    PyObject * pModule = NULL;
    PyObject * pFunc   = NULL;

    PyRun_SimpleString("import os");
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("pyScriptPath = os.getcwd()+'\\PyScript'");
    PyRun_SimpleString("sys.path.insert(0,pyScriptPath)");
    PyRun_SimpleString("if (not os.path.exists(pyScriptPath)) : os.mkdir(pyScriptPath)");
    PyRun_SimpleString("print sys.path");
    PyRun_SimpleString("print '\\n'");


    PyObject *pTopModObj=PyImport_ImportModule("__main__");
    PyObject * pObj=PyByteArray_FromStringAndSize("1234",4);
    if(pObj){
        if(0==PyObject_SetAttrString(pTopModObj,"testBa",pObj)){
            PyRun_SimpleString("print 'pyScriptPath=' ,pyScriptPath");
        }
        PyRun_SimpleString("print 'testBa=' ,testBa");
    }

    PyRun_SimpleString("del pyScriptPath");
    PyObject *measureObj = Py_BuildValue("[d,d,d,s]",1.0,2.0,3.0,"mm");
    PyObject_SetAttrString(pTopModObj,"measureObj",measureObj);
    PyRun_SimpleString("print 'measureObj=' ,measureObj");

    PyObject * pModuleNameObj = PyUnicode_DecodeUTF8("test",4,NULL);
    if(pModuleNameObj){
        pModule=PyImport_Import(pModuleNameObj);
//        pModule=PyImport_ImportModule("test");
        if(pModule){
            pFunc = PyObject_GetAttrString(pModule,"func");
            if(pFunc){
                PyObject * pArgs = PyTuple_New(1);
                PyTuple_SetItem(pArgs,0,measureObj);

                PyObject * pValue = PyObject_CallObject(pFunc,pArgs);
                int res[3]={0};
//                res[0]=PyInt_AsLong(PyList_GetItem(pValue,0));
//                res[1]=PyInt_AsLong(PyList_GetItem(pValue,1));
//                res[2]=PyInt_AsLong(PyList_GetItem(pValue,2));
                printf("return type = %s \n",pValue->ob_type->tp_name);
                PyArg_Parse(pValue,"(iii)",res,res+1,res+2);
                printf("[%d,%d,%d]",res[0],res[1],res[2]);
                Py_CLEAR(pValue);
                Py_CLEAR(pArgs);
                Py_CLEAR(pFunc);
            }


            double array_1[] = {1,2,3,4,5,6,7,8};
            npy_intp dims_1[] = { 2, 3};
            PyObject *mat_1 = PyArray_SimpleNewFromData(2, dims_1, NPY_DOUBLE, array_1);

            pFunc = PyObject_GetAttrString(pModule,"func1");
            if(pFunc){
                PyObject * pArgs = PyTuple_New(1);
                PyTuple_SetItem(pArgs,0,mat_1);
                PyObject * pValue = PyObject_CallObject(pFunc,pArgs);
                if(pValue && 1==PyObject_IsInstance(pValue,(PyObject *)&PyArray_Type)){
                    PyArrayObject *mat_3;
                    PyArray_OutputConverter(pValue, &mat_3);
                    npy_intp *shape = PyArray_SHAPE(mat_3);
                    double *array_3 = (double*)PyArray_DATA(mat_3);
                    if(array_3){
                        printf("numpy result:\n");
                        for (int i = 0; i < shape[0]; i++) {
                            for (int j = 0; j < shape[1]; j++) {
                                printf("%f",array_3[i*shape[1] + j]);
                                printf("\t");
                            }
                            printf("\n");
                        }
                    }
                    Py_CLEAR(mat_3);
                }

                Py_CLEAR(pValue);
                Py_CLEAR(pArgs);
                Py_CLEAR(pFunc);
            }
            Py_CLEAR(mat_1);
        }
    }

    Py_CLEAR(pTopModObj);
    Py_CLEAR(pObj);
    Py_CLEAR(measureObj);
    Py_CLEAR(pModuleNameObj);
    Py_CLEAR(pModule);

    Py_Finalize();
    return 0;
}
